package com.springboot.util;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifIFD0Directory;
import com.springboot.entity.Project;
import org.apache.commons.io.FilenameUtils;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.*;
import java.text.Format;
import java.text.SimpleDateFormat;
// import org.apache.commons.codec.binary.Base64;
import java.util.*;

public class AppHelper {

    /**
     * 获取参数列表
     */
    public static Map<String, Object> getMap(Object... values) {
        Map<String, Object> map = new HashMap<>();
        for (int i = 0; i < values.length; i += 2)
            map.put((String) values[i], values[i + 1]);
        return map;
    }

    /**
     * 以指定格式获取当前时间格式字符串
     */
    public static String getDate(String format) {
        if (format == null)
            format = "yyyy-MM-dd";
        Date date = new Date();
        Format simple = new SimpleDateFormat(format);
        return simple.format(date);
    }

    /**
     * 获取随机序列码
     */
    public static String UUIDCode() {
        UUID uuid = UUID.randomUUID();
        String code = uuid.toString();
        return code.toUpperCase();
    }

    /**
     * 获取request
     */
    public static HttpServletRequest getRequest() {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) attributes).getRequest();
        return request;
    }

    /**
     * 获取response
     */
    public static HttpServletResponse getResponse() {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = ((ServletRequestAttributes) attributes).getResponse();
        return response;
    }

    /**
     * 获取session
     */
    public static HttpSession getSession() {
        HttpServletRequest request = getRequest();
        return request.getSession(true);
    }

    /**
     * 添加数据至session
     */
    public static void pushMap(String key, Object value) {
        HttpSession session = getSession();
        session.setAttribute(key, value);
    }

    /**
     * 从session获取数据
     */
    public static Object findMap(String key) {
        HttpSession session = getSession();
        return session.getAttribute(key);
    }

    /**
     * 从session移除数据
     */
    public static void removeMap(String key) {
        HttpSession session = getSession();
        session.removeAttribute(key);
    }

    /**
     * 保存图片
     */
    public static void saveImage(String data, String path, String name) {
        try {
            byte[] bytes = Base64.getMimeDecoder().decode(data.substring(22));
            // byte[] bytes = Base64.decodeBase64(name.substring(22));
            for (int i = 0; i < bytes.length; i++)
                bytes[i] = bytes[i] < 0 ? bytes[i] += 256 : bytes[i];
            FileUtil.mkdir(path);
            String pathname = StrUtil.join("/", path, name + ".png");
            OutputStream output = new FileOutputStream(pathname);
            output.write(bytes);
            output.flush();
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据文件名称查找文件数组中的文件
     *
     * @param files 文件数组
     * @param name  文件名称，不包含前缀和后缀
     * @param type  查找方式：type - 根据文件类型查找，name - 根据文件名称查找
     * @return - 返回MultipartFile对象
     */
    public static MultipartFile getFile(MultipartFile[] files, String name, String type) {
        if (Objects.equals(type, "name"))
            return Arrays.asList(files).stream().filter(file -> Objects.equals(FilenameUtils.getBaseName(file.getOriginalFilename()), name)).findFirst().orElse(null);
        if (Objects.equals(type, "type"))
            return Arrays.asList(files).stream().filter(file -> Objects.equals(file.getContentType(), name)).findFirst().orElse(null);
        return null;
    }

    public static void move(MultipartFile file, File dest) {
        try {
            file.transferTo(dest);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 查看图片旋转角度
     */
    public static int getRotate(String filePath) {
        try {
            File file = new File(filePath);
            Metadata metadata = ImageMetadataReader.readMetadata(file);
            Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
            if (directory != null) {
                int rotate = directory.getInt(274);
                if (rotate == 6)
                    return 90;
                if (rotate == 3)
                    return 180;
                if (rotate == 8)
                    return 270;
            }
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 对象转换为xml文件
     */
    public static void convert(Project project, String path) {
        try {
            JAXBContext context = JAXBContext.newInstance(project.getClass());
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            OutputStream stream = new ByteArrayOutputStream();
            marshaller.marshal(project, stream);
            byte[] bytes = stream.toString().getBytes();
            FileUtil.writeBytes(bytes, path);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * xml文件转换为对象
     */
    public static <T> T convert(Class<T> iclass, File file) {
        try {
            JAXBContext context = JAXBContext.newInstance(iclass);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            return Convert.convert(iclass, unmarshaller.unmarshal(file));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static XSSFWorkbook getWorkbook(MultipartFile file) {
        try {
            InputStream stream = file.getInputStream();
            return new XSSFWorkbook(stream);
        } catch (IOException e) {
            return null;
        }
    }

    public static String getString(XSSFCell cell) {
        try {
            return cell.getStringCellValue();
        } catch (Exception e) {
            return "";
        }
    }

    public static double getNumber(XSSFCell cell) {
        try {
            return cell.getNumericCellValue();
        } catch (Exception e) {
            return 0;
        }
    }

    public static String substring(String text, int beg, int end) {
        if (text != null && end == 0)
            end = text.length();
        return StrUtil.sub(text, beg, end);
    }
}
